/*
 * timer.cpp
 *
 * Created: 06.05.2012 22:25:41
 *  Author: Maxim Karban <maxim.karban@gmail.com>
 */ 

#include "halcyon_v1.h"

#include <avr/io.h>
#include <avr/interrupt.h>

#include "sys_events.h"
#include "bosch_pressure.h"
#include "mma7455.h"
#include "debug.h"

//timings variables for 40ms intervals
#define systime_div         1 // x/2 intervals
#define SYSTIME_1S          (25<<systime_div)
#define SYSTIME_5S          ((SYSTIME_1S*5)<<systime_div)
#define SYSTIME_200MS       (5<<systime_div)
#define SYSTIME_500MS       (12<<systime_div)

#define SYSTIME_BOSCH_BMP085_DIV   1
#define SYSTIME_BOSCH_SMD500_DIV   0

int systime = SYSTIME_500MS;


#if defined(BARO)
#define HLOCK_BARO_INIT false, false,
#else
#define HLOCK_BARO_INIT 
#endif
#if defined(ACCEL)
#define HLOCK_ACCEL_INIT false, false,
#else
#define HLOCK_ACCEL_INIT 
#endif
#if defined(BARO) | defined(ACCEL)
#define HLOCK_BARO_ACCEL_INIT false,
#else
#define HLOCK_BARO_ACCEL_INIT 
#endif
#if defined(GPS)
#define HLOCK_GPS_INIT false, false, false
#else
#define HLOCK_GPS_INIT 
#endif

sHalcyonLocks hLock = { HLOCK_BARO_INIT HLOCK_ACCEL_INIT HLOCK_BARO_ACCEL_INIT HLOCK_GPS_INIT};


SensorState sensorState = SS_INIT_1;

//each 40ms = 25Hz
//2.7ms max time in interrupt
//in case BMP085 we can get even faster to get better response time
//now 20ms = 50Hz
ISR(TIMER1_COMPA_vect){//, ISR_NOBLOCK){

  //debug_pin_on;
  switch(sensorState){
  case SS_INIT_1:
#if defined(BARO)
    BSStartPress();
#endif
    sensorState = SS_INIT_2;
    break;
  case SS_INIT_2:
#if defined(BARO)
    BSReadPress();
    BSStartTemp();
#endif
    sensorState = SS_NORMAL_1;
    break;
  case SS_NORMAL_1:
#if defined(BARO)
    BSReadTemp();
    BSStartPress();
    hLock.pressure_data_ready = true;
#endif
#if defined(ACCEL)
    MMAGetAccel();
    hLock.accel_data_ready = true;
#endif
    sensorState = SS_NORMAL_2;
    break;
  case SS_NORMAL_2:
#if defined(BARO)
    BSReadPress();
    BSStartTemp();
    hLock.pressure_data_ready = true;
#endif
#if defined(ACCEL)
    MMAGetAccel();
    hLock.accel_data_ready = true;
#endif
    sensorState = SS_NORMAL_1;
    break;
  }
  
  systime--;
  
  if(systime <= 0){
    systime = SYSTIME_5S;
    hLock.mark5s = true;
  }
  if((systime/(SYSTIME_200MS))*(SYSTIME_200MS) == systime){
    hLock.mark200ms = true;
  }
  if((systime/(SYSTIME_500MS))*(SYSTIME_500MS) == systime){
    hLock.mark500ms = true;
  }
  if((systime/(SYSTIME_1S))*(SYSTIME_1S) == systime){
    hLock.mark1s = true;
  }

  //debug_pin_off;
}


void sysEventsInit(){
  void timer1Init();
}

void timer1Init(){
    //WGM mode CTC on OCR1A
  TCCR1A = (0 << COM1A1) | (0 << COM1A0) | (0 << WGM11) | (0 << WGM10) ;// 0b1000000;//0x80
  TCCR1B = (0 << WGM13) | (1 << WGM12) | (1 << CS12) | (0 << CS11) | (1 << CS10);// 0b00000101;//0x05
  TCCR1C = 0x00;

  OCR1A = 156 >> systime_div;//~40ms for smd500 ~20ms for bmp085, does not works, CPU speed not enough
  
  TIMSK1 = 1 << OCIE1A;

}